import http       from 'axios'
import Loading    from './StaticLoading'
import {baseUrl}  from '@/common/config'
import tokenUtils from '@/utils/storage'
import store      from "@/store/store";
import {
	exportFile,
	otherErrorHandle,
	responseFailedHandle,
}                 from './utils'

const loading = Loading.getInstance()

const request = http.create({
	baseURL        : baseUrl,
	timeout        : 60000, //todoList 由 10000 改成 60000
	withCredentials: true,
	crossDomain    : true,
})

request.defaults = {}

request.interceptors.request.use(
	req => {
		
		req.headers['access_token']  = store.state.token;
		req.headers['_session_user'] = store.state.sessionUser;
		req.headers['_session_org']  = store.state.sessionOrg;
		
		return req
	},
	error => Promise.reject(error)
)

request.interceptors.response.use(
	response => {
		const {
			      status,
			      data   : payload = {},
			      headers: {'content-disposition': disposition}
		      } = response
		if (disposition) {
			return exportFile(response)
		}
		else if (status >= 400) {
			responseFailedHandle(status, response)
		}
		else {
			const {code, data, msg} = payload
			// if (+code >= 200 && +code <= 300) {
			if (String(code) === '0') {
				const {payload} = data
				if (payload) {
					return Promise.resolve(payload || {})
				}
				else {
					return Promise.resolve(data || {})
				}
			}
			else {
				responseFailedHandle(code, response, msg)
			}
		}
	},
	error => {
		if (error && error.response) {
			const {status} = error.response
			responseFailedHandle(status, error.response)
		}
		else {
			return otherErrorHandle()
		}
	})

export default class {
	/**
	 * get接口方式
	 * @param path
	 * @param model
	 * @param extra 拓展配置
	 */
	get(path, model = {}, extra) {
		let getPath = path
		if (Object.keys(model).length) {
			const query = this.qs(model)
			getPath     = `${path}${query ? `?${query}` : ''}`
		}
		return this.fetch(getPath, 'get', {}, extra)
	}
	
	/**
	 * patch接口方式
	 * @param path
	 * @param data
	 * @param extra 拓展配置
	 */
	patch(path, data, extra) {
		this._requestBodyClearNull(data)
		return this.fetch(path, 'patch', data, extra)
	}
	
	/**
	 * put接口方式
	 * @param path
	 * @param data
	 * @param extra 拓展配置
	 */
	put(path, data, extra) {
		this._requestBodyClearNull(data)
		return this.fetch(path, 'put', data, extra)
	}
	
	/**
	 * post接口方式
	 * @param path
	 * @param data
	 * @param extra 拓展配置
	 */
	post(path, data, extra) {
		this._requestBodyClearNull(data)
		return this.fetch(path, 'post', data, extra)
	}
	
	/**
	 * delete接口方式
	 * @param path
	 * @param extra 拓展配置
	 */
	delete(path, extra) {
		return this.fetch(path, 'delete', extra)
	}
	
	/**
	 * do fetch
	 */
	async fetch(path, method = 'get', data, extra = {}) {
		const params = {url: path, method, data, ...extra}
		loading.begin()
		return await request(params).finally(() => loading.end())
	}
	
	/**
	 * 对象转 url
	 * @param o
	 * @returns {string}
	 */
	qs = (o = {}) => {
		const arr = []
		Object.keys(o).forEach(key => {
			if (Object.prototype.hasOwnProperty.call(o, key) && (o[key] || o[key] === 0)) {
				arr.push(`${key}=${o[key]}`)
			}
		})
		return arr.join('&')
	}
	
	/**
	 * private
	 *  对象 转 FormData
	 * @param o
	 * @returns {FormData}
	 */
	o2formData(o = {}) {
		const formData = new FormData()
		Object.keys(o).forEach(key => {
			// const value = o[key] instanceof File ? o[key] : JSON.stringify(o[key])
			const value = o[key]
			if (value || value === 0) {
				formData.append(key, value)
			}
		})
		return formData
	}
	
	/**
	 * 休眠 毫秒
	 * @param time
	 * @returns {Promise<any>}
	 */
	sleep = time => {
		return new Promise((resolve) => setTimeout(resolve, time))
	}
	
	/**
	 * 去除 requestBody中的 空/null 字符串
	 * @param o
	 * @private
	 */
	_requestBodyClearNull(o = {}) {
		Object.keys(o).forEach(key => {
			const value = o[key]
			if (!value && value !== 0) {
				delete o[key]
			}
		})
	}
}
